﻿using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Mvvm.Models;
using Newtonsoft.Json.Linq;

namespace MvvM.Services;

public class EmotionAIService
{
    private const string x_appid = "c51397bf";
    private const string api_secret = "MWI0MTI5NmQxYThjNTAzN2VlNzY0ZWRm";
    private const string api_key = "c97565b1bbe4be1990733370f1b6c153";
    private const string hostUrl = "https://spark-api.xf-yun.com/v4.0/chat";

    private ClientWebSocket _webSocket;
    private static CancellationTokenSource _cancellationSource = new CancellationTokenSource();
    private CancellationToken _cancellation = _cancellationSource.Token;

            // 新方法用于生成情感数据描述文本并调用大模型
        public async Task<string> AnalyzeEmotionDataAndGetSuggestions(List<ChatData> chatDataList)
        {
            // 分析情感数据
            var emotionData = AnalyzeEmotionData(chatDataList);

            // 生成描述文本
            string description = GenerateEmotionDataDescription(emotionData);

            // 调用大模型并返回结果
            return await ConnectAndSendMessageAsync(description);
        }

        // 分析情感数据的方法
        private (int PositiveCount, int NeutralCount, int NegativeCount, Dictionary<string, int> ToneCounts)
            AnalyzeEmotionData(List<ChatData> chatDataList)
        {
            int positiveCount = 0;
            int neutralCount = 0;
            int negativeCount = 0;
            Dictionary<string, int> toneCounts = new Dictionary<string, int>();

            foreach (var chatData in chatDataList)
            {
                if (chatData.Emotion == "optimistic")
                {
                    positiveCount++;
                }
                else if (chatData.Emotion == "neutral")
                {
                    neutralCount++;
                }
                else if (chatData.Emotion == "pessimistic")
                {
                    negativeCount++;
                }

                if (!toneCounts.ContainsKey(chatData.EmotionTone))
                {
                    toneCounts[chatData.EmotionTone] = 1;
                }
                else
                {
                    toneCounts[chatData.EmotionTone]++;
                }
            }

            return (positiveCount, neutralCount, negativeCount, toneCounts);
        }

        // 生成情感数据描述文本的方法
        private string GenerateEmotionDataDescription((int PositiveCount, int NeutralCount, int NegativeCount, Dictionary<string, int> ToneCounts) emotionData)
        {
            StringBuilder descriptionBuilder = new StringBuilder();

            descriptionBuilder.Append($"积极消息数量为：{emotionData.PositiveCount} 条。");
            descriptionBuilder.Append($"中性消息数量为：{emotionData.NeutralCount} 条。");
            descriptionBuilder.Append($"消极消息数量为：{emotionData.NegativeCount} 条。");

            foreach (var tone in emotionData.ToneCounts)
            {
                descriptionBuilder.Append($"{tone.Key} 语气的消息数量为：{tone.Value} 条。");
            }

            return descriptionBuilder.ToString();
        }

    
    public async Task<string> ConnectAndSendMessageAsync(string message)
    {
        string authUrl = GetAuthUrl();
        string wsUrl = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
        _webSocket = new ClientWebSocket();
        try
        {
            await _webSocket.ConnectAsync(new Uri(wsUrl), _cancellation);
            var request = new JsonRequest
            {
                header = new Header { app_id = x_appid, uid = "12345" },
                parameter = new Parameter
                {
                    chat = new Chat
                    {
                        domain = "4.0Ultra",
                        temperature = 0.5,
                        max_tokens = 1024,
                    }
                },
                payload = new Payload
                {
                    message = new Message
                    {
                        text = new List<Content>
                        {
                            new Content { role = "system", content = "你是一个情感分析助手，现在我将提供一些聊天记录的情感数据统计信息，包括积极消息数量、中性消息数量、消极消息数量以及各种语气消息的数量。请你根据这些数据，以一种友好、通俗易懂且像是在与朋友交流的方式，生成相应的反馈,帮助用户客观地了解双方的聊天的情感变化，提供实用沟通建议，内容不需要再叙述数据了，不要包含*，要简洁明了，不要包含套话，不要出现我的建议字样，以中文形式显示，不要包含英文" },
                            new Content { role = "user", content = message },
                        }
                    }
                }
            };
            string jsonString = JsonSerializer.Serialize(request);
            var frameData = Encoding.UTF8.GetBytes(jsonString);
            await _webSocket.SendAsync(new ArraySegment<byte>(frameData), WebSocketMessageType.Text, true, _cancellation);

            byte[] receiveBuffer = new byte[1024];
            WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), _cancellation);
            string resp = "";
            while (!result.CloseStatus.HasValue)
            {
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                    JObject jsonObj = JObject.Parse(receivedMessage);
                    int code = (int)jsonObj["header"]["code"];
                    if (code == 0)
                    {
                        int status = (int)jsonObj["payload"]["choices"]["status"];
                        JArray textArray = (JArray)jsonObj["payload"]["choices"]["text"];
                        string content = (string)textArray[0]["content"];
                        resp += content;
                        if (status != 2)
                        {
                            // Continue receiving messages
                        }
                        else
                        {
                            int totalTokens = (int)jsonObj["payload"]["usage"]["text"]["total_tokens"];
                            return $"{resp}";
                        }
                    }
                    else
                    {
                        return $"请求报错：{receivedMessage}";
                    }
                }
                else if (result.MessageType == WebSocketMessageType.Close)
                {
                    return "已关闭WebSocket连接";
                }
                result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), _cancellation);
            }
        }
        catch (Exception e)
        {
            return e.Message;
        }
        finally
        {
            if (_webSocket != null)
            {
                await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, _cancellation);
            }
        }

        throw new InvalidOperationException();
    }

    private string GetAuthUrl()
    {
        string date = DateTime.UtcNow.ToString("r");
        Uri uri = new Uri(hostUrl);
        StringBuilder builder = new StringBuilder("host: ").Append(uri.Host).Append("\n").Append("date: ").Append(date).Append("\n").Append("GET ").Append(uri.LocalPath).Append(" HTTP/1.1");
        string sha = HMACsha256(api_secret, builder.ToString());
        string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", api_key, "hmac-sha256", "host date request-line", sha);
        string newUrl = "https://" + uri.Host + uri.LocalPath;
        string path1 = "authorization" + "=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization));
        date = date.Replace(" ", "%20").Replace(":", "%3A").Replace(",", "%2C");
        string path2 = "date" + "=" + date;
        string path3 = "host" + "=" + uri.Host;
        newUrl = newUrl + "?" + path1 + "&" + path2 + "&" + path3;
        return newUrl;
    }

    public static string HMACsha256(string apiSecretIsKey, string builder)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(apiSecretIsKey);
        using (HMACSHA256 hMACSHA256 = new HMACSHA256(bytes))
        {
            byte[] hash = hMACSHA256.ComputeHash(Encoding.UTF8.GetBytes(builder));
            return Convert.ToBase64String(hash);
        }
    }
}

// JSON classes
public class JsonRequest
{
    public Header header { get; set; }
    public Parameter parameter { get; set; }
    public Payload payload { get; set; }
}

public class Header
{
    public string app_id { get; set; }
    public string uid { get; set; }
}

public class Parameter
{
    public Chat chat { get; set; }
}

public class Chat
{
    public string domain { get; set; }
    public double temperature { get; set; }
    public int max_tokens { get; set; }
}

public class Payload
{
    public Message message { get; set; }
}

public class Message
{
    public List<Content> text { get; set; }
}

public class Content
{
    public string role { get; set; }
    public string content { get; set; }
}
